package com.new4net.exe_stream.instruction.impl;

import com.new4net.exe_stream.meta.ExecutionContext;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

public class DoWhileInstruction<R> extends WhileInstruction<R> {
    public DoWhileInstruction(String instructionName, Consumer<ExecutionContext.InstructionContext> consumer, Function<ExecutionContext.InstructionContext, R> body, Predicate<ExecutionContext.InstructionContext> predicate) {
        super(instructionName, consumer,predicate, body);
    }
    @Override
    public void exe() {
        initor.accept(instructionContext);
        exeBody();

    }

    private void exeBody() {
        do{
            retVal=body.apply(instructionContext);
            executionContext.addInstructionContext(instructionContext);
            instructionContext=executionContext.buildInstructionContext();
        }while (predicate.test(instructionContext));
    }

    protected void exeRetry() {
        exeBody();
    }



    public void retryAll(){

        synchronized (this){
            try {
                retryPrev();
                int i=0;
                do{
                    boolean flag = false;
                    if(instructionContexts.size()>i){
                        instructionContext=instructionContexts.get(i);
                        instructionContext.clear();
                    }else{
                        instructionContext=executionContext.buildInstructionContext();
                        flag=true;
                    }


                    retVal=body.apply(instructionContext);
                    if(flag){
                        
                        executionContext.addInstructionContext(instructionContext);
                        instructionContexts.add(instructionContext);
                        instructionContext=executionContext.buildInstructionContext();
                    }

                    i++;
                }while (predicate.test(instructionContext));
                post();
            } catch (Throwable e) {
                fault(e);

            }
        }



    }
    @Override
    public String getInstuctionType() {
        return "doWhile";
    }

}
